///////////////////////////////////////////////////////////////////////////////
// This file is taken directly from pyR, (C) Nial Peters 2011
//
// Copyright (C) Nial Peters 2012
//
// This file is part of AvoScan.
//
// AvoScan is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AvoScan is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AvoScan.  If not, see <http://www.gnu.org/licenses/>.
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


/* The code in this file is modified from
 * http://blog.enthought.com/python/numpy-arrays-with-pre-allocated-memory/
 */
#include "autodealloc_numpy.h"

///////////////////////////////////////////////////////////////////////////////

static void
_autodealloc_dealloc(AutoDeallocObject *self)
{
	//free memory associated with array
	free(self->memory);

	//free self
	self->ob_type->tp_free((PyObject *)self);
}

///////////////////////////////////////////////////////////////////////////////

static PyTypeObject AutoDeallocType = {
	PyObject_HEAD_INIT(NULL)
	0, /*ob_size*/
	"mydeallocator", /*tp_name*/
	sizeof(AutoDeallocObject), /*tp_basicsize*/
	0, /*tp_itemsize*/
	_autodealloc_dealloc, /*tp_dealloc*/
	0, /*tp_print*/
	0, /*tp_getattr*/
	0, /*tp_setattr*/
	0, /*tp_compare*/
	0, /*tp_repr*/
	0, /*tp_as_number*/
	0, /*tp_as_sequence*/
	0, /*tp_as_mapping*/
	0, /*tp_hash */
	0, /*tp_call*/
	0, /*tp_str*/
	0, /*tp_getattro*/
	0, /*tp_setattro*/
	0, /*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT, /*tp_flags*/
	"Internal deallocator object", /* tp_doc */
};

///////////////////////////////////////////////////////////////////////////////

PyObject * createAutoDeallocNumpyArray(int nd, npy_intp* dims, int typenum, void *data){
	PyObject *arr, *newobj;

	arr = PyArray_SimpleNewFromData(nd, dims, typenum, data);

	if (arr == NULL){
		SET_ERR("Failed to create numpy array wrapper", RUN_ERR);
		goto fail;
	}

	newobj = (PyObject*)PyObject_New(AutoDeallocObject, &AutoDeallocType);

	if (newobj == NULL) {
		SET_ERR("Failed to create auto-dealloc object", RUN_ERR);
		goto fail;
	}

	((AutoDeallocObject *)newobj)->memory = data;

	PyArray_BASE(arr) = newobj;

	return arr;

	fail:
		Py_XDECREF(arr);
		return NULL;

}

///////////////////////////////////////////////////////////////////////////////

void import_autodealloc_numpy(void){
	import_array();
	AutoDeallocType.tp_new = PyType_GenericNew;
	if (PyType_Ready(&AutoDeallocType) < 0){
		return;
	}
}

///////////////////////////////////////////////////////////////////////////////

